/**
* All Rights Reserved , Copyright (C) 2021 , 青岛鼎信通讯股份有限公司
*
* MpmProjectChangeService
* 项目立项信息变更
*
* 修改纪录
* 2021-07-14 版本：1.0 wudaliang 创建。
* @version 版本：1.0
* @author 作者：wudaliang
* 创建日期：2021-07-14
*/
package com.topscomm.mpm.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.cbo.service.ICboMessageAppService;
import com.topscomm.cbo.service.ICboMessageSysService;
import com.topscomm.main.hessian.IBaseChangeLogService;
import com.topscomm.main.hessian.IMmsProvinceCityMatchinfoService;
import com.topscomm.mpm.MpmSystemConst;
import com.topscomm.mpm.pojo.*;
import com.topscomm.mpm.service.IMpmProjectCustomerService;
import com.topscomm.mpm.service.IMpmProjectProductInfoService;
import com.topscomm.mpm.service.IMpmProjectProductOutInfoService;
import com.topscomm.mpm.utils.ConvertTimeUtil;
import com.topscomm.mpm.utils.MessageUtil;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.FlowDatacodeCache;
import com.topscomm.tap.common.SessionUserBean;

import java.util.*;
import java.util.stream.Collectors;

import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.mpm.service.IMpmProjectChangeService;
import com.topscomm.mpm.service.impl.auto.MpmProjectChangeServiceAuto;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.util.PrimaryKeyUtil;
import org.springframework.transaction.annotation.Transactional;

@Service(value = "mpmProjectChangeService")
@Scope(value = "singleton")
public class MpmProjectChangeService extends MpmProjectChangeServiceAuto implements IMpmProjectChangeService {
	FlowDatacodeCache flowDatacodeCache=new FlowDatacodeCache();
	DatacodeCache datacodeCache = new DatacodeCache();
	protected List<Map<String,Object>> flowidList=new ArrayList();
	@Autowired
	private MpmProjectService mpmProjectService;
	@Autowired
	private MpmProjectSaleService mpmProjectSaleService;

	@Autowired
	private IMpmProjectProductInfoService mpmProjectProductInfoService;
	@Autowired
	private IMpmProjectProductOutInfoService mpmProjectProductOutInfoService;

	@Autowired
	private IMpmProjectCustomerService mpmProjectCustomerService;

	@Autowired
	private IMmsProvinceCityMatchinfoService mmsProvinceCityMatchinfoService;
	@Autowired
	private MpmProjectBidDateHistoryService mpmProjectBidDateHistoryService;
	@Autowired
	private MpmProjectUniversalChangeService mpmProjectUniversalChangeService;
	@Autowired
	private IBaseChangeLogService baseChangeLogService;
	@Autowired
	private ICboMessageAppService cboMessageAppService;
	@Autowired
	private ICboMessageSysService cboMessageSysService;
	@Autowired
	private MpmProjectProductInfoHisService mpmProjectProductInfoHisService;
	@Autowired
	private MpmProjectProductOutInfoHisService mpmProjectProductOutInfoHisService;

	@Override
	public void setDispFields(Map<String, Object> mapRow, DatacodeCache datacodeCache) {
		super.setDispFields(mapRow, datacodeCache);
		if (mapRow.get("deptname1") != null) {
			String temp1 = ConvertUtil.convertToString(mapRow.get("deptname1"));
			String temp2 = ConvertUtil.convertToString(mapRow.get("deptname2"));
			String temp3 = ConvertUtil.convertToString(mapRow.get("deptname3"));
			String dispdeptname = this.mmsProvinceCityMatchinfoService.getDispdeptname(temp1, temp2, temp3);
			mapRow.put("dispdeptname", dispdeptname);
		} else {
			mapRow.put("dispdeptname", "");
		}
	}

	/**
	 * @author: wudaliang
	 * @date: 2021-07-14
	 * @param entity
	 * @throws ServiceException
	 * @description:单号生成
	 * @modify:
	 */
	@Override
	protected void beforeInsert(BasicEntity entity){
		super.beforeInsert(entity);
		if (entity.getId() <= 0) {// 赋值Id和单号
			long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
			entity.setId(arrayId[0]);
			String docNo = String.valueOf(arrayId[0]);
			docNo = docNo.substring(0, 6) + docNo.substring(9);
			entity.setValue(MpmProjectChangeEntity.FieldDocno, docNo);
		}
	}

	@SneakyThrows
	@Override
	protected void beforeSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
		super.beforeSubmit(entity, sessionUserBean);
		MpmProjectChangeEntity mpmProjectChangeEntity = (MpmProjectChangeEntity) entity;
		this.flowidList= flowDatacodeCache
			.getApprovalFlowListMap("ApprovalFlow_MpmProjectChange",
					mpmProjectChangeEntity.getUsercode(), "sortcode");
		if(flowidList.size()>0){
			mpmProjectChangeEntity.setFlowid(ConvertUtil.convertToLong(flowidList.get(0).get("id")));
		}else{
			throw new ServiceException("没有匹配的审批流，请联系管理员！");
		}
		// 立项变更存储basechangelog表变更字段信息
		this.approvalSaveChangeLog(mpmProjectChangeEntity);
		// 立项变更赋值审批流程标识字段
		this.setNeedApprovalLineType(mpmProjectChangeEntity);
	}

	/**
	 * @author: chengengwei
	 * @date: 2021-09-08
	 * @description: 保存前处理JSONArray类型数据
	 * @modify:
	 */
	@Override
	protected void updateBefore(Map<String, Object> map) throws ServiceException {
		// 需要先转化成实体再更新，防止前台传递的值为Json格式从而更新失败
		Object o = map.get(MpmProjectChangeEntity.FieldProductrange2);
		if (o instanceof JSONArray) {
			map.put(MpmProjectChangeEntity.FieldProductrange2, o.toString());
		}
		// 需要先转化成实体再更新，防止前台传递的值为Json格式从而更新失败
		Object obj = map.get(MpmProjectChangeEntity.FieldProductoutrange2);
		if (obj instanceof JSONArray) {
			map.put(MpmProjectChangeEntity.FieldProductoutrange2, obj.toString());
		}
		if (map.containsKey("customerlist") && map.get("customerlist") != null) {
			// 更新客户信息
			JSONArray jsonArray = (JSONArray)map.get("customerlist");
			List<Map> customerList = JSONObject.parseArray(jsonArray.toJSONString(), Map.class);
			customerList.forEach(cus -> {
			    cus.put("sourceid", ConvertUtil.convertToLong(map.get("id")));
			    cus.put("id", 0);
            });
			this.mpmProjectCustomerService.removeAndAddRecord(customerList);
		}
		// 内外部产品历史子表信息
		mpmProjectProductInfoHisService.removeAndAddRecord(map);
		mpmProjectProductOutInfoHisService.removeAndAddRecord(map);
	}

	public void updateLevelHistory(Map<String,Object> paraMap){
		String oldprojectlevel = paraMap.get("oldprojectlevel").toString();
		String newprojectlevel = paraMap.get("newprojectlevel").toString();
        if (StringUtil.isEmpty(oldprojectlevel) || StringUtil.isEmpty(newprojectlevel) || oldprojectlevel.equals(newprojectlevel)) {
            return;
        }
		int oldlevel = Integer.parseInt(oldprojectlevel);
		int newlevel = Integer.parseInt(newprojectlevel);
		JSONObject record = new JSONObject();
		String[] levelArray={"A","B","C","D"};
		record.put("oldprojectlevel",levelArray[oldlevel]);
		record.put("newprojectlevel",levelArray[newlevel]);
		//更新项目等级变更历史字段
		HashMap<String, Object> updateMap = new HashMap<>();
		updateMap.put("id",paraMap.get("id"));
		updateMap.put("levelhistory2",record.toString());
		this.update(updateMap);
	}

	/**
	 * @author: wudaliang
	 * @date: 2021-07-16
	 * @param: projectcode2
	 * @param: mpmProjectChangeEntity
	 * @description: 立项变更审批完后
	 * @return: void
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void projectChangeUpdate(String projectcode2, MpmProjectChangeEntity mpmProjectChangeEntity) throws Exception {
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" projectcode ='{0}' and enabled=1 ",projectcode2);
		List<MpmProjectEntity> mpmProjectEntities = mpmProjectService.queryByWhere(sql.toString());
		MpmProjectEntity mpmProjectEntity = mpmProjectEntities.get(0);
		Date oldPlanEndDate = mpmProjectEntity.getPlanenddate();
		sql.clear();
		sql.appendSingle("id ='{0}' and enabled=1",mpmProjectEntity.getId());
		MpmProjectSaleEntity mpmProjectSaleEntity = mpmProjectSaleService.queryByWhere(sql.toString()).get(0);
		// 判断是否为第一次变更，若为第一次，则将立项信息保存到变更表中，firstvisionflag字段值设置为1
		this.saveFirstVersionInfo(mpmProjectEntity, mpmProjectSaleEntity);
		// 判断是否为其他等级变为A级，修改会议开始时间
		if (!MpmSystemConst.ProjectLevel.A.equals(mpmProjectChangeEntity.getOriginalprojectlevel()) && MpmSystemConst.ProjectLevel.A.equals(mpmProjectChangeEntity.getProjectlevel2())) {
			this.changeToA(mpmProjectEntity, mpmProjectSaleEntity);
		}
		// 判断是否为A级变为其他等级，修改会议结束时间
		if (MpmSystemConst.ProjectLevel.A.equals(mpmProjectChangeEntity.getOriginalprojectlevel()) && !MpmSystemConst.ProjectLevel.A.equals(mpmProjectChangeEntity.getProjectlevel2())) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			ConvertTimeUtil.convertToThisWeekSunday(calendar);
			mpmProjectEntity.setMeetenddate(calendar.getTime());
		}
		mpmProjectEntity.setProjectname(mpmProjectChangeEntity.getProjectname2());
		mpmProjectEntity.setProjectlevel(mpmProjectChangeEntity.getProjectlevel2());
		mpmProjectEntity.setProjectdefaultlevel(mpmProjectChangeEntity.getProjectdefaultlevel2());
		mpmProjectEntity.setBidcycle(mpmProjectChangeEntity.getBidcycle2());
		mpmProjectEntity.setPlanstartdate(mpmProjectChangeEntity.getPlanstartdate2());
		mpmProjectEntity.setPlanenddate(mpmProjectChangeEntity.getPlanenddate2());
		// 主表finishdate字段不改变，不需要同步
		// mpmProjectEntity.setFinishdate(mpmProjectChangeEntity.getFinishdate2());
		mpmProjectEntity.setActualenddate(mpmProjectChangeEntity.getActualenddate2());

		mpmProjectEntity.setCurrentmilepost(mpmProjectChangeEntity.getCurrentmilepost2());

		mpmProjectEntity.setCurrentmilepoststate(mpmProjectChangeEntity.getCurrentmilepoststate2());

		mpmProjectEntity.setAbnormalstate(mpmProjectChangeEntity.getAbnormalstate2());

		mpmProjectEntity.setAbnormalreason(mpmProjectChangeEntity.getAbnormalreason2());

		mpmProjectEntity.setProjectmanager(mpmProjectChangeEntity.getProjectmanager2());

		mpmProjectEntity.setProjectmanagercode(mpmProjectChangeEntity.getProjectmanagercode2());

		mpmProjectEntity.setSponsor(mpmProjectChangeEntity.getSponsor2());

		mpmProjectEntity.setSponsorcode(mpmProjectChangeEntity.getSponsorcode2());

		mpmProjectEntity.setOwner(mpmProjectChangeEntity.getOwner2());

		mpmProjectEntity.setOwnercode(mpmProjectChangeEntity.getOwnercode2());
		// 如果存在原项目等级，且原项目等级和现项目等级不一致，说明项目等级发生了更改，此时需要更新levelhistory字段
		String oldprojectlevel = ConvertUtil.convertToString(mpmProjectChangeEntity.getOriginalprojectlevel());
		String newprojectlevel = ConvertUtil.convertToString(mpmProjectChangeEntity.getProjectlevel2());
		if (!StringUtil.isEmpty(oldprojectlevel) && !newprojectlevel.equals(oldprojectlevel)) {
			int oldlevel = Integer.parseInt(oldprojectlevel);
			int newlevel = Integer.parseInt(newprojectlevel);
			JSONObject record = new JSONObject();
			String[] levelArray = {"A", "B", "C", "D"};
			record.put("oldprojectlevel", levelArray[oldlevel]);
			record.put("newprojectlevel", levelArray[newlevel]);
			mpmProjectEntity.setLevelhistory(record.toString());
		}

		mpmProjectEntity.setBackground(mpmProjectChangeEntity.getBackground2());

		mpmProjectEntity.setProductrange(mpmProjectChangeEntity.getProductrange2());

		mpmProjectEntity.setProjectmoney(mpmProjectChangeEntity.getProjectmoney2());

		mpmProjectEntity.setTarget(mpmProjectChangeEntity.getTarget2());

		mpmProjectEntity.setAchievements(mpmProjectChangeEntity.getAchievements2());

		mpmProjectEntity.setImportance(mpmProjectChangeEntity.getImportance2());

		mpmProjectEntity.setSummary(mpmProjectChangeEntity.getSummary2());

		mpmProjectEntity.setChangelevelreason(mpmProjectChangeEntity.getChangelevelreason2());

		mpmProjectEntity.setDecisionusercode(mpmProjectChangeEntity.getDecisionusercode2());

		mpmProjectEntity.setDecisionusername(mpmProjectChangeEntity.getDecisionusername2());
		mpmProjectEntity.setClientcode(mpmProjectChangeEntity.getClientcode2());
		mpmProjectEntity.setClientdept(mpmProjectChangeEntity.getClientdept2());
		mpmProjectEntity.setClientsourcetype(mpmProjectChangeEntity.getClientsourcetype2());
		mpmProjectEntity.setClientname(mpmProjectChangeEntity.getClientname2());
		// 修改外部产品内容
		mpmProjectEntity.setProductoutrange(mpmProjectChangeEntity.getProductoutrange2());
		mpmProjectEntity.setDeptname1(mpmProjectChangeEntity.getDeptname1());
		mpmProjectEntity.setDeptname2(mpmProjectChangeEntity.getDeptname2());
		mpmProjectEntity.setDeptname3(mpmProjectChangeEntity.getDeptname3());
		mpmProjectEntity.setClientlevel(mpmProjectChangeEntity.getClientlevel2());
		// 修改项目类型（推广类、销售类）
		if (!ObjectUtil.isEmpty(mpmProjectChangeEntity.getPmoprojecttype2())) {
			mpmProjectEntity.setPmoprojecttype(mpmProjectChangeEntity.getPmoprojecttype2());
		}
		mpmProjectService.updateEntity(mpmProjectEntity);
		// 更新附加表
		mpmProjectSaleEntity.setChanceclue(mpmProjectChangeEntity.getChanceclue2());
		mpmProjectSaleEntity.setParticipatemoney(mpmProjectChangeEntity.getParticipatemoney2());

		mpmProjectSaleEntity.setChanceclue(mpmProjectChangeEntity.getChanceclue2());

		mpmProjectSaleEntity.setPurchasepattern(mpmProjectChangeEntity.getPurchasepattern2());

		mpmProjectSaleEntity.setBidinfo(mpmProjectChangeEntity.getBidinfo2());

		mpmProjectSaleEntity.setBidbegindate(mpmProjectChangeEntity.getBidbegindate2());

		mpmProjectSaleEntity.setBidenddate(mpmProjectChangeEntity.getBidenddate2());

		mpmProjectSaleEntity.setBidsigndate(mpmProjectChangeEntity.getBidsigndate2());

		mpmProjectSaleEntity.setClientsupport(mpmProjectChangeEntity.getClientsupport2());

		mpmProjectSaleEntity.setClientdemand(mpmProjectChangeEntity.getClientdemand2());

		mpmProjectSaleEntity.setDecisionmode(mpmProjectChangeEntity.getDecisionmode2());

		mpmProjectSaleEntity.setCompetitor(mpmProjectChangeEntity.getCompetitor2());

		mpmProjectSaleEntity.setSwot(mpmProjectChangeEntity.getSwot2());
		mpmProjectSaleEntity.setClientname(mpmProjectChangeEntity.getClientname2());
		mpmProjectSaleEntity.setClientdept(mpmProjectChangeEntity.getClientdept2());
		mpmProjectSaleEntity.setProjectsource(mpmProjectChangeEntity.getProjectsource2());
		mpmProjectSaleEntity.setDemandbegindate(mpmProjectChangeEntity.getDemandbegindate2());
		mpmProjectSaleEntity.setDemandenddate(mpmProjectChangeEntity.getDemandenddate2());
		mpmProjectSaleService.updateEntity(mpmProjectSaleEntity);

		// 更新任命和策划的项目名称和项目经理字段
		this.updateRelevantRecord(mpmProjectEntity);
//		mpmProjectBidDateHistoryService.changeBidDate(mpmProjectChangeEntity.getId(),mpmProjectEntity.getId());
		// 更新内外部产品子表内容
		mpmProjectProductInfoService.updateFromHistory(mpmProjectChangeEntity.getId());
		mpmProjectProductOutInfoService.updateFromHistory(mpmProjectChangeEntity.getId());
		// 插入客户信息
		sql.clear();
		sql.appendSingle(" sourcetype = '{0}' and sourceid = {1} ", mpmProjectChangeEntity.tableName,
				mpmProjectChangeEntity.getId());
		List<Map<String, Object>> customers = this.mpmProjectCustomerService.queryMapByWhere(sql.toString());
		List<Map> insertBatchList = customers.stream().map(item -> {
			item.put("id", 0);
			item.put("sourcetype", mpmProjectEntity.tableName);
			item.put("sourceid", mpmProjectEntity.getId());
			return item;
		}).collect(Collectors.toList());
		this.mpmProjectCustomerService.removeAndAddRecord(insertBatchList);
		// 项目计划完成时间更新之后，执行超期检测方法
		if (mpmProjectChangeEntity.getPlanenddate2().compareTo(oldPlanEndDate) > 0) {
			 mpmProjectService.updateAbnormalState(mpmProjectEntity.getProjectcode());
		}
		// 如果项目等级变更为C级且项目为春季/秋季攻势，projectattack置为空，变更项目编号
        if (!StringUtil.isEmpty(mpmProjectEntity.getProjectattack()) && MpmSystemConst.ProjectLevel.C.equals(mpmProjectChangeEntity.getProjectlevel2())) {
            mpmProjectService.addProjectAttackFirst(mpmProjectChangeEntity.getProjectcode2(), "");
        }
	}

	/**
	 * @author: chengengwei
	 * @date: 2021-09-24
	 * @description: 立项变更审批通过后更新其他相关表的记录
	 * @modify:
	 */
	private void updateRelevantRecord(MpmProjectEntity mpmProjectEntity) {
		StringBufferProxy sql = new StringBufferProxy();
		// 同步任命表
		sql.appendSingle(" update {0} set projectname = '{1}', projectmanager = '{2}', " +
				"projectmanagercode = '{3}', appointmenttitle = '{4}' , owner = '{5}', ownercode = '{6}'" +
						", sponsor = '{7}', sponsorcode = '{8}' where projectcode = '{9}' ",
				MpmProjectAppointmentEntity.tableName, mpmProjectEntity.getProjectname(),
				mpmProjectEntity.getProjectmanager(), mpmProjectEntity.getProjectmanagercode(),
				mpmProjectEntity.getProjectname() + "项目组任命", mpmProjectEntity.getOwner(), mpmProjectEntity.getOwnercode(),
				mpmProjectEntity.getSponsor(), mpmProjectEntity.getSponsorcode(), mpmProjectEntity.getProjectcode());
		this.selectExecute(sql.toString());
		sql.clear();
		// 同步策划表
		sql.appendSingle(" update {0} set projectname = '{1}', proposalname = '{2}' where projectcode = '{3}' ",
				MpmProjectPlanEntity.tableName, mpmProjectEntity.getProjectname(),
				mpmProjectEntity.getProjectname() + "策划书", mpmProjectEntity.getProjectcode());
		this.selectExecute(sql.toString());
	}

	/**
	 * @author: chengengwei
	 * @date: 2021-09-13
	 * @description: 保存初次立项信息
	 * @modify:
	 */
	private void saveFirstVersionInfo(MpmProjectEntity mpmProjectEntity, MpmProjectSaleEntity mpmProjectSaleEntity) {
		StringBufferProxy whereSql = new StringBufferProxy();
		whereSql.appendSingle(" {0} = '{1}' and state = '9' ", MpmProjectChangeEntity.FieldProjectcode2,
				mpmProjectEntity.getProjectcode());
		int count = this.getCount(whereSql.toString());
		// 判断是否为初次变更，若是则插入记录
		if (count == 0) {
			MpmProjectChangeEntity firstVersionRecord = new MpmProjectChangeEntity();
            // 是否为初次立项版本记录字段置为1
            firstVersionRecord.setFirstvisionflag(1);
            firstVersionRecord.setProjectcode2(mpmProjectEntity.getProjectcode());
			firstVersionRecord.setProjectname2(mpmProjectEntity.getProjectname());
			firstVersionRecord.setProjectlevel2(mpmProjectEntity.getProjectlevel());
			firstVersionRecord.setProjectdefaultlevel2(mpmProjectEntity.getProjectdefaultlevel());
			firstVersionRecord.setBidcycle2(mpmProjectEntity.getBidcycle());
			firstVersionRecord.setPlanstartdate2(mpmProjectEntity.getPlanstartdate());
			firstVersionRecord.setPlanenddate2(mpmProjectEntity.getPlanenddate());
			firstVersionRecord.setFinishdate2(mpmProjectEntity.getFinishdate());
			firstVersionRecord.setActualenddate2(mpmProjectEntity.getActualenddate());
			firstVersionRecord.setCurrentmilepost2(mpmProjectEntity.getCurrentmilepost());
			firstVersionRecord.setCurrentmilepoststate2(mpmProjectEntity.getCurrentmilepoststate());
			firstVersionRecord.setAbnormalstate2(mpmProjectEntity.getAbnormalstate());
			firstVersionRecord.setAbnormalreason2(mpmProjectEntity.getAbnormalreason());
			firstVersionRecord.setProjectmanager2(mpmProjectEntity.getProjectmanager());
			firstVersionRecord.setProjectmanagercode2(mpmProjectEntity.getProjectmanagercode());
			firstVersionRecord.setSponsor2(mpmProjectEntity.getSponsor());
			firstVersionRecord.setSponsorcode2(mpmProjectEntity.getSponsorcode());
			firstVersionRecord.setOwner2(mpmProjectEntity.getOwner());
			firstVersionRecord.setOwnercode2(mpmProjectEntity.getOwnercode());
			firstVersionRecord.setLevelhistory2(mpmProjectEntity.getLevelhistory());
			firstVersionRecord.setBackground2(mpmProjectEntity.getBackground());
			firstVersionRecord.setProductrange2(mpmProjectEntity.getProductrange());
			firstVersionRecord.setProjectmoney2(mpmProjectEntity.getProjectmoney());
			firstVersionRecord.setTarget2(mpmProjectEntity.getTarget());
			firstVersionRecord.setAchievements2(mpmProjectEntity.getAchievements());
			firstVersionRecord.setImportance2(mpmProjectEntity.getImportance());
			firstVersionRecord.setSummary2(mpmProjectEntity.getSummary());
			firstVersionRecord.setChangelevelreason2(mpmProjectEntity.getChangelevelreason());
			firstVersionRecord.setSubmitdate(mpmProjectEntity.getSubmitdate());
			firstVersionRecord.setState(9);
			firstVersionRecord.setOrgcode(mpmProjectEntity.getOrgcode());
			firstVersionRecord.setOrgname(mpmProjectEntity.getOrgname());
			firstVersionRecord.setDeptcode(mpmProjectEntity.getDeptcode());
			firstVersionRecord.setDeptname(mpmProjectEntity.getDeptname());
			firstVersionRecord.setDecisionusercode2(mpmProjectEntity.getDecisionusercode());
			firstVersionRecord.setDecisionusername2(mpmProjectEntity.getDecisionusername());
			firstVersionRecord.setUsercode(mpmProjectEntity.getUsercode());
			firstVersionRecord.setUsername(mpmProjectEntity.getUsername());
			firstVersionRecord.setApplydeptcode(mpmProjectEntity.getApplydeptcode());
			firstVersionRecord.setApplydeptname(mpmProjectEntity.getApplydeptname());
			firstVersionRecord.setApplyorgcode(mpmProjectEntity.getApplyorgcode());
			firstVersionRecord.setApplyorgname(mpmProjectEntity.getApplyorgname());
			// 项目信息销售表
			firstVersionRecord.setChanceclue2(mpmProjectSaleEntity.getChanceclue());
			firstVersionRecord.setParticipatemoney2(mpmProjectSaleEntity.getParticipatemoney());
			firstVersionRecord.setPurchasepattern2(mpmProjectSaleEntity.getPurchasepattern());
			firstVersionRecord.setBidbegindate2(mpmProjectSaleEntity.getBidbegindate());
			firstVersionRecord.setBidenddate2(mpmProjectSaleEntity.getBidenddate());
			firstVersionRecord.setBidsigndate2(mpmProjectSaleEntity.getBidsigndate());
			firstVersionRecord.setClientsupport2(mpmProjectSaleEntity.getClientsupport());
			firstVersionRecord.setClientdemand2(mpmProjectSaleEntity.getClientdemand());
			firstVersionRecord.setDecisionmode2(mpmProjectEntity.getProjectcode());
			firstVersionRecord.setCompetitor2(mpmProjectSaleEntity.getCompetitor());
			firstVersionRecord.setSwot2(mpmProjectSaleEntity.getSwot());
			firstVersionRecord.setClientname2(mpmProjectSaleEntity.getClientname());
			firstVersionRecord.setClientdept2(mpmProjectSaleEntity.getClientdept());
			firstVersionRecord.setClientsourcetype2(mpmProjectEntity.getClientsourcetype());
			firstVersionRecord.setClientcode2(mpmProjectEntity.getClientcode());

			firstVersionRecord.setProjectsource2(mpmProjectSaleEntity.getProjectsource());
			MpmProjectChangeEntity changeEntity = this.insert(firstVersionRecord);
			// 插入客户信息
			whereSql.clear();
			whereSql.appendSingle(" sourcetype = '{0}' and sourceid = {1} ", mpmProjectEntity.tableName,
					mpmProjectEntity.getId());
			List<MpmProjectCustomerEntity> customers = this.mpmProjectCustomerService.queryByWhere(whereSql.toString());
			List<BasicEntity> insertBatchList = customers.stream().map(item -> {
				item.setId(0);
				item.setSourcetype(MpmProjectChangeEntity.tableName);
				item.setSourceid(changeEntity.getId());
				return (BasicEntity) item;
			}).collect(Collectors.toList());
			this.mpmProjectCustomerService.insertBatch(insertBatchList);
		}
	}

	/**
	 * @author: chengengwei
	 * @date: 2021-11-18
	 * @description: 保存前新增客户信息
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public MpmProjectChangeEntity insert(Map<String, Object> paraMap) {
		MpmProjectChangeEntity entity = new MpmProjectChangeEntity();
		entity.convertFromMap(paraMap);
		entity = this.insert(entity);
		// 更新客户信息
		if (paraMap.containsKey("customerlist") && paraMap.get("customerlist") != null) {
			JSONArray jsonArray = (JSONArray)paraMap.get("customerlist");
			List<Map> customerList = JSONObject.parseArray(jsonArray.toJSONString(), Map.class);
			for (Map m : customerList) {
				m.put("id", 0);
				m.put("sourcetype", entity.getTableName());
				m.put("sourceid", entity.getId());
			}
			this.mpmProjectCustomerService.removeAndAddRecord(customerList);
		}
		return entity;
	}

	@Override protected void deleteBefore(String whereSql) {
		List<Map<String,Object>> deleteMaps = this.queryMapByWhere(whereSql);
		String ids = deleteMaps.stream().map(a->ConvertUtil.convertToString(a.get("id"))).collect(Collectors.joining(","));
		super.deleteBefore(whereSql);
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" sourcetype = '{0}' and sourceid in {1}",MpmProjectChangeEntity.tableName,ids);
		mpmProjectCustomerService.deleteByWhere(sql.toString());
	}

	/***
	 * @description: 立项不需要审批提交
	 * @param paraMap
	 * @return
	 * @author: jiangtao1
	 * @date: 2022/7/15 11:37
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void executeLocalSubmit(Map<String, Object> paraMap) throws Exception {
		// 内外部产品历史子表信息
		mpmProjectProductInfoHisService.removeAndAddRecord(paraMap);
		mpmProjectProductOutInfoHisService.removeAndAddRecord(paraMap);
		MpmProjectChangeEntity entity = new MpmProjectChangeEntity();
			entity.convertFromMap(paraMap);
			if(0!=entity.getState()) {
				throw new ServiceException("该单据已提交过，不允许重复提交");
			}
			entity.setLatestphase("结束");
			entity.setState(9);
			entity.setSubmitdate(new Date());
			this.updateEntity(entity);
			// 脚本处理
		// 更新立项信息表
		this.projectChangeUpdate(entity.getProjectcode2(),entity);
		// 产生变更记录表
		mpmProjectUniversalChangeService.createRecordAfterApproval(MpmProjectChangeEntity.tableName,ConvertUtil.convertToString(entity.getId()));
	}
	/***
	 * @description: 立项变更时将B/C级项目修改为A级项目,修改会议开始结束时间
	 * @return
	 * @author: houyuhang
	 * @date: 2022/12/14
	 * @modify:
	 */
	public void changeToA(MpmProjectEntity mpmProjectEntity,MpmProjectSaleEntity mpmProjectSaleEntity) {
		// 策划审批未完成，使用当前日期下一周的周一作为会议开始日期，策划审批完成，使用策划日期下一周的周一作为会议开始日期
		Calendar calendar = Calendar.getInstance();
		if (ObjectUtil.isEmpty(mpmProjectEntity.getDesignenddate())) {
			calendar.setTime(new Date());
		} else {
			calendar.setTime(mpmProjectEntity.getDesignenddate());
		}
		calendar.add(Calendar.DATE, MpmSystemConst.ChangeWeekDay);
		ConvertTimeUtil.convertToThisWeekMonday(calendar);
		mpmProjectEntity.setMeetbegindate(calendar.getTime());
	}
	/***
	 * @description: 立项变更审批时保存basechangelog表内容
	 * @return
	 * @author: houyuhang
	 * @date: 2023/02/03
	 * @modify:
	 */
	public void approvalSaveChangeLog(MpmProjectChangeEntity mpmProjectChangeEntity) throws Exception {
		// 删除上次的basechangelog
		baseChangeLogService.deleteByWhere(" topsourcetype='"+mpmProjectChangeEntity.getTableName()+"'"
				+ " and topsourceid='"+mpmProjectChangeEntity.getId()+"'");
		// 保存basechangelog信息
		this.getBaseChangeEntity(mpmProjectChangeEntity.convertToMap());
	}
	/***
	 * @description: 获取变更具体内容
	 * @return
	 * @author: houyuhang
	 * @date: 2023/02/03
	 * @modify:
	 */
	public void getBaseChangeEntity(Map<String, Object> inputMap) throws Exception {
		// 去除map中key值的后缀2，保证字段对应值一致
		Map<String, Object> replaceMap = new HashMap<>();
		for(Map.Entry<String, Object> tempMap : inputMap.entrySet()) {
			replaceMap.put(StringUtils.removeEnd(tempMap.getKey(), "2"), tempMap.getValue());
		}
		// 获取变更version记录
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" projectcode2 = '{0}' and newadd = '1' and changetype = '1' ", replaceMap.get("projectcode"));
		int version = this.getCount(sql.toString()) + 1;
		// 获取项目主表信息
		sql.clear();
		sql.appendSingle(" enabled = 1 and projectcode = '{0}' ", replaceMap.get("projectcode"));
		Map<String, Object> projectMap = mpmProjectService.queryObjectByWhere(sql.toString()).convertToMap();
		// 获取sale表信息
		MpmProjectSaleEntity mpmProjectSaleEntity = mpmProjectSaleService.queryById(ConvertUtil.convertToString(projectMap.get("id")));
		// 拼接比对字段
		Map<String, Object> changeMap = new HashMap<String, Object>();
		changeMap.put("topsourcetype",MpmProjectChangeEntity.tableName);
		changeMap.put("topsourceid", ConvertUtil.convertToString(replaceMap.get("id")));
		changeMap.put("sourcetype", MpmProjectChangeEntity.tableName);
		changeMap.put("sourceid", ConvertUtil.convertToString(replaceMap.get("id")));
		changeMap.put("newmap", replaceMap);
		changeMap.put("oldmap", projectMap);
		changeMap.put("baselogoperatetype", MpmSystemConst.BaseLogOperateTypeEnum.Edit);
		changeMap.put("version", version);
		Map<String, Object> changeResMap = this.getMainChangeLogEntity(changeMap);
		if (changeResMap != null) {
			baseChangeLogService.insertLogMap(changeResMap);
		}
		// 获取项目sale表信息
		Map<String, Object> saleMap = new HashMap<>();
		saleMap.put("topsourcetype",MpmProjectChangeEntity.tableName);
		saleMap.put("topsourceid", ConvertUtil.convertToString(replaceMap.get("id")));
		saleMap.put("sourcetype", MpmProjectSaleEntity.tableName);
		saleMap.put("sourceid", mpmProjectSaleEntity.getId());
		saleMap.put("newmap", replaceMap);
		saleMap.put("oldmap", mpmProjectSaleEntity.convertToMap());
		saleMap.put("baselogoperatetype", MpmSystemConst.BaseLogOperateTypeEnum.Edit);
		saleMap.put("version", version);
		Map<String, Object> saleResMap = this.getMainChangeLogEntity(saleMap);
		if (saleResMap != null) {
			baseChangeLogService.insertLogMap(saleResMap);
		}
	}
	/***
	 * @description: 审批流程标识赋值
	 * @return
	 * @author: houyuhang
	 * @date: 2023/02/06
	 * @modify:
	 */
	public void setNeedApprovalLineType(MpmProjectChangeEntity mpmProjectChangeEntity) throws Exception {
		// 获取主表信息
		String projectcode = mpmProjectChangeEntity.getProjectcode2();
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" enabled = 1 and projectcode = '{0}' ", projectcode);
		MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(sql.toString());
		String oldProjectLevel = mpmProjectEntity.getProjectlevel();
		String newProjectLevel = mpmProjectChangeEntity.getProjectlevel2();
		if (!MpmSystemConst.ProjectLevel.A.equals(oldProjectLevel) && !MpmSystemConst.ProjectLevel.A.equals(newProjectLevel)) {
			// 原非A级项目，变更后非A级项目，走旧审批流程
			mpmProjectChangeEntity.setNeedapprovalline(MpmSystemConst.ChangeNeedApprovalLine.Others);
		} else if (!MpmSystemConst.ProjectLevel.A.equals(oldProjectLevel) || !MpmSystemConst.ProjectLevel.A.equals(newProjectLevel)) {
			// 原A级项目，变更非A级项目或原非A级项目，变更为A级项目，owner审批
			mpmProjectChangeEntity.setNeedapprovalline(MpmSystemConst.ChangeNeedApprovalLine.Line);
		} else {
			// A级项目，项目经理为省总的变更，只修改计划完成时间的变更，不需要审批;其他需要owner审批
			Map<String, Object> paraMap = new HashMap<>();
			paraMap.put("topSourceType", MpmProjectChangeEntity.tableName);
			paraMap.put("topSourceId", mpmProjectChangeEntity.getId());
			List<Map<String, Object>> baseChangeLog = baseChangeLogService.queryChangeLogByOptions(paraMap);
			boolean onlychangetime = this.setOnlyChangeTime(baseChangeLog);
			if (mpmProjectService.queryIsProvinceManager(mpmProjectEntity.getProjectmanagercode()) || onlychangetime) {
				mpmProjectChangeEntity.setNeedapprovalline(MpmSystemConst.ChangeNeedApprovalLine.NoLine);
			} else {
				mpmProjectChangeEntity.setNeedapprovalline(MpmSystemConst.ChangeNeedApprovalLine.Line);
			}
		}
	}
	/***
	 * @description: 立项变更内容是否改变或是否只改变了时间
	 * @return
	 * @author: houyuhang
	 * @date: 2023/02/06
	 * @modify:
	 */
	public boolean setOnlyChangeTime(List<Map<String, Object>> baseChangeLog) {
		// 变更没有修改字段值
		if (CollectionUtil.isEmpty(baseChangeLog)) {
			return true;
		}
		// 变更只修改了计划开始完成日期
		if (baseChangeLog.size() == 1 && MpmProjectChangeEntity.tableName.equals(ConvertUtil.convertToString(baseChangeLog.get(0).get("sourcetype")))) {
			JSONArray jsonArray = JSONArray.parseArray(ConvertUtil.convertToString(baseChangeLog.get(0).get("content")));
			boolean flag = true;
			for (int i = 0; i < jsonArray.size(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				if (!"planstartdate".equals(jsonObject.getString("code")) && !"planenddate".equals(jsonObject.getString("code"))) {
					flag = false;
					break;
				}
			}
			return flag;
		}
		return false;
	}
	/***
	 * @description: 提醒项目PMO和省区PMO立项变更的内容
	 * @return
	 * @author: houyuhang
	 * @date: 2023/02/06
	 * @modify:
	 */
	public void sendMessageChangeToPMO(MpmProjectChangeEntity mpmProjectChangeEntity, MpmProjectEntity mpmProjectEntity) throws Exception {
		// 获取消息发送人（项目PMO和省区PMO）
		List<Map<String, Object>> receiverList = this.getMessageReceiverPMO(mpmProjectEntity.getDeptcommoncode());
		if (CollectionUtil.isEmpty(receiverList)) {
			return;
		}
		// 获取变更内容，如果只变更了时间或未变更具体内容，不发送消息
		Map<String, Object> paraMap = new HashMap<>();
		paraMap.put("topSourceType", MpmProjectChangeEntity.tableName);
		paraMap.put("topSourceId", mpmProjectChangeEntity.getId());
		List<Map<String, Object>> baseChangeLog = baseChangeLogService.queryChangeLogByOptions(paraMap);
		if (CollectionUtil.isEmpty(baseChangeLog)) {
		    return;
        }
		if (this.setOnlyChangeTime(baseChangeLog)) {
			return;
		}
		// 发送消息
		List<Map<String, Object>> appList = new ArrayList<>(), sysList = new ArrayList<>();
		Map<String, Object> appMap = new HashMap<>(), sysMap = new HashMap<>();
		String title = "销售项目立项变更通知";
		String projectLevel = datacodeCache.getValueDynamic("MpmProjectLevel", mpmProjectEntity.getProjectlevel(), "code", "name");
		// 获取变更内容
		String changeInfo = this.getChangeInfoDetail(baseChangeLog);
		StringBufferProxy content = new StringBufferProxy();
		content.appendSingle("【{0}级项目：{1}】立项变更已完成，{2}请知悉。", projectLevel, mpmProjectEntity.getProjectname(), changeInfo);
		for (Map<String, Object> receiver : receiverList) {
			// app推送
			appMap = MessageUtil.createMessageAppMap(ConvertUtil.convertToString(receiver.get("usercode")), title, content.toString(), mpmProjectEntity.getId(),
					MpmProjectChangeEntity.tableName, 0);
			// 系统消息
			sysMap = MessageUtil.createMessageSysMap(ConvertUtil.convertToString(receiver.get("usercode")), ConvertUtil.convertToString(receiver.get("username")), title, content.toString(),
					mpmProjectEntity.getId(), MpmProjectChangeEntity.tableName);
			// 封装
			appList.add(appMap);
			sysList.add(sysMap);
		}
		// 消息批量插入
		cboMessageAppService.insertList(appList);
		cboMessageSysService.insertList(sysList);
	}
	/***
	 * @description: 获取立项变更修改具体字段
	 * @return
	 * @author: houyuhang
	 * @date: 2023/02/06
	 * @modify:
	 */
	public String getChangeInfoDetail(List<Map<String, Object>> baseChangeLog) {
		List<String> listStr = new ArrayList<>();
		for (Map<String, Object> logMap : baseChangeLog) {
			JSONArray jsonArray = JSONArray.parseArray(ConvertUtil.convertToString(logMap.get("content")));
			for (int i = 0; i < jsonArray.size(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				listStr.add(jsonObject.getString("name"));
			}
		}
		return listStr.stream().collect(Collectors.joining("、")) + "已变更，";
	}
}
